package 反射6;

import com.alibaba.druid.pool.DruidDataSourceFactory;
import org.apache.commons.beanutils.BeanUtils;

import javax.sql.DataSource;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

public class MyhandleDbReflection<T> {
//    private static String driverClassName;
//    private static String url;
//    private static String userName;
//    private static String password;
///*
//解耦，将MySQL的账号密码驱动和地址封装起来
//
// */
//    static {
//        try {
//            InputStream resourceAsStream = MyhandleDbReflection.class.getClassLoader().getResourceAsStream("反射6\\jdbc.properties");
//            Properties properties = new Properties();
//            properties.load(resourceAsStream);
//            driverClassName = properties.getProperty("driverClassName");
//            url = properties.getProperty("url");
//            userName = properties.getProperty("userName");
//            password = properties.getProperty("password");
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//    }

    public static Connection getConnection() throws SQLException {
        Connection connection = null;
        try {
            Properties properties = new Properties();
            FileInputStream fileInputStream = new FileInputStream("src//反射6//jdbc.properties");
            properties.load(fileInputStream);
//使用德鲁伊数据库连接池技术
            DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);

            connection = dataSource.getConnection();
            System.out.println("connection = " + connection);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return connection;

    }

    /**
     * 数据的更新 反射  解耦
     * Sql  update a set x='',y='',
     * 可变参数  。。。
     */
    public static int updata(String sql, Object... o) throws SQLException {
        int f = 0;
        //获取连接
        Connection connection = MyhandleDbReflection.getConnection();
        PreparedStatement statement = connection.prepareStatement(sql);
        //获取字符串中参数个数
        ParameterMetaData parameterMetaData = statement.getParameterMetaData();
        System.out.println("parameterMetaData = " + parameterMetaData);
        int num = parameterMetaData.getParameterCount();
        System.out.println("num=" + num);
        if (num != 0) {
            for (int i = 0; i < num; i++) {
                statement.setObject(i + 1, o[i]);
            }
        }
        f = statement.executeUpdate();
        return f;

    }

    //封装获取链接的方法
//    public static Connection conn() throws Exception {
//        Connection connection = DriverManager.getConnection(url, userName, password);
//        return connection;
//    }

    // 封装预编译的方法
    public static PreparedStatement preparedStatement(String sql, Object... prem) throws Exception {
        Connection conn = getConnection();
        PreparedStatement pre = conn.prepareStatement(sql);
        ParameterMetaData parameterMetaData = pre.getParameterMetaData();
        int count = parameterMetaData.getParameterCount();
        if (count != 0) {
            for (int i = 0; i < count; i++) {
                pre.setObject(i + 1, prem[i]);
            }
        }
        return pre;
    }

    //封装插入删除
    // public static int insert(String sql,Object...prem)throws Exception{
    //   PreparedStatement pre =conn.prepareStatement(sql);
    //    int i=pre(sql,prem).executeUpdate();
    //   close(sql,prem);
    //  return i;
    /*
*表中的记录映射到Javabean实体类的每一个属性上
     */
    public static <T> T queryBean(String sql, Class<T> cls, Object... parameters) throws Exception {
        //1.定义需要的对象
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        T t = null;
        //2.连接数据库
        connection = MyhandleDbReflection.getConnection();
//        ----------------------
        statement = preparedStatement(sql, parameters);
        resultSet = statement.executeQuery();
        ResultSetMetaData metaData = resultSet.getMetaData();
        //     System.out.println("测试元数据metaData="+metaData);
        while (resultSet.next()) {
            t = cls.getConstructor().newInstance();
            //获取这一行记录字段的个数
            int count = metaData.getColumnCount();
            for (int i = 1; i <= count; i++) {
                //表中的记录映射到Javabean实体类的每一个属性上
                BeanUtils.setProperty(t,
                        metaData.getColumnName(i),
                        resultSet.getObject(i));
            }
        }
        return t;

    }
/**顾安洋
 * 连接数据库、获取预编译对象，执行sql,获取结果集合，获取元数据,
 *将数据库以HashMap的方式展现出来
 *
 */

    public static HashMap<String,Object>queryMap(String sql,Object...parameters)throws Exception{
        HashMap<String,Object>stringObjectHashMap=null;
         PreparedStatement Prestatement=preparedStatement(sql,parameters);
        ResultSet resultSet = Prestatement.executeQuery();
        ResultSetMetaData metaData = resultSet.getMetaData();
        int count=metaData.getColumnCount();
        stringObjectHashMap=new HashMap<>();
        while (resultSet.next()){

            for (int i = 1; i < count; i++) {
                stringObjectHashMap.put(metaData.getColumnName(i),resultSet.getObject(i));
            }
        }
        return stringObjectHashMap;
    }


/**顾安洋
 * 连接数据库、获取预编译对象，执行sql,获取结果集合，获取元数据,
 * 将数据库以数组的方式展现出来
 *
 *
 */

   public static Object[]queryArrey(String sql, Object...parameters) throws Exception{

       Connection connection = MyhandleDbReflection.getConnection();
      PreparedStatement statement=  preparedStatement(sql,parameters);
       ResultSet resultSet = statement.executeQuery();
       ResultSetMetaData metaData = resultSet.getMetaData();
       int count=metaData.getColumnCount();
       Object[] objects=new Object[count];
       resultSet.next();
       for (int i = 1; i < count; i++) {
           objects[i]=resultSet.getObject(i);
       }
       return objects;
    }
    /**
     *将数据库以数组放到集合中的形式展现出来
     *
     */

    public static ArrayList<Map> queryMapList(String sql, Object...parameters)throws Exception{
       MyhandleDbReflection.getConnection();
        PreparedStatement statement = preparedStatement(sql, parameters);
        ResultSet resultSet = statement.executeQuery();
        ResultSetMetaData metaData = resultSet.getMetaData();
        ArrayList<Map>maps=null;
        maps = new ArrayList<>();
        while (resultSet.next()){
            int count=metaData.getColumnCount();
            HashMap<String, Object> stringObjectHashMap = new HashMap<>();
            for (int c = 1; c < count; c++) {
                stringObjectHashMap.put(metaData.getColumnName(c),resultSet.getObject(c));

            }maps.add(stringObjectHashMap);
        }
        return maps;
    }
    /*顾安洋
    *
    * 封装结束的方法
    * */

    public static void close(Connection connection,ResultSet resultSet){
        try {
            if (connection!=null){
                connection.close();
            }
            if (resultSet!=null){
                resultSet.close();

            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}




